home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Varsity Update 1998 August
/
SGI Varsity Update 1998 August.iso
/
dist
/
SpeedShop.idb
/
usr
/
demos
/
SpeedShop
/
generic
/
generic.c.z
/
generic.c
Wrap
C/C++ Source or Header
|
1998-07-29
|
36KB
|
1,701 lines
/* generic.c - generic program to use for testing performance tools */
#include <sys/types.h>
#include <dirent.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <malloc.h>
#include <sys/stat.h>
#include <dlfcn.h>
#include <signal.h>
#include <sys/prctl.h>
#include <ulocks.h>
#include <fcntl.h>
/* parameters defining various tasks */
#define BUFSIZE 16384
#define THRASHMB 32
#define DIRNAME "/usr/include"
#define IONAME "/unix"
#define DYNSOROUTINE "dlslave_routine"
#define DYNSONAME "./dlslave.so"
#define NSPROCS 8
#define NBEERBOTTLES 5
#define NSPROCMALLOCS 5
/* the default script */
#define DEFAULT_SCRIPT "ll.u.cvt.d.i.f.dso"
void Scriptstring(char *); /* routine execute a scenario */
void genLog(char *); /* write to log */
void clone(char *); /* fork copy of self to run string */
void reapAll(void); /* reap all children */
void reapSig(int); /* reap a child after getting SIGCLD */
/* various behavior routines */
int adddso(void); /* add a DSO and call a routine in the DSO */
int beerbottles(void); /* exec beerbottles */
int callsystem(void); /* call system to generate another process */
int cvttrap(void); /* generate unimplemented FP traps */
int dirstat(void); /* scan a directory, and stat its files */
int exectest(void); /* fork, and exec a program in the child */
int fpetraps(void); /* generate a bunch of fpe's */
int forceabort(void); /* force a SEGV by dereferencing NULL */
int iofile(void); /* do some iofile */
int iotest(void); /* various other io syscall tests */
int libdso(void); /* link and call a routine in a DSO */
int libdsoclose(void); /* dlclose a DSO */
int linklist(void); /* build a linked list of structures */
int mallocerrors(void); /* make verious kinds of malloc errors */
int mallocerrors_extra(void); /* malloc errors - extra */
int mp_mallocs(void); /* multi-processes calling "me" and "mex" */
int memthrash(void); /* thrash around in memory */
int sproctest(void); /* sproc, and run a routine in the child */
int usrtime(void); /* use a bunch of user time */
void anneal(); /* array annealing test */
/* lookup table for behavior scripts */
struct scripttab {
char *name;
int (*function)(void);
};
struct scripttab scripttab[] = {
"bb", beerbottles,
"callsys", callsystem,
"cvt", cvttrap,
"d", dirstat,
"ex", exectest,
"f", fpetraps,
"segv", forceabort,
"i", iofile,
"I", iotest,
"ll", linklist,
#ifndef NONSHARED
"dso", libdso,
"dsoclose", libdsoclose,
"adddso", adddso,
"me", mallocerrors,
"mex", mallocerrors_extra,
"mpmes", mp_mallocs, /* MP malloc-error tests (me + mex) */
#endif
"t", memthrash,
"sp", sproctest,
"u", usrtime,
NULL, NULL
};
void sproctestchild(void *); /* sproc child code */
void sproctestgrandchild(void *); /* sproc grandchild code */
static struct timeval starttime; /* starting time - first timestamp */
static struct timeval ttime; /* last-recorded timestamp */
static struct timeval deltatime;
int pagesize;
main(unsigned argc, char **argv)
{
int i;
/* initialize the timestamp */
(void) gettimeofday(&starttime, NULL);
/* set up to reap any children */
(void) sigset(SIGCHLD, (SIG_PF)reapSig);
if(argc == 1) {
Scriptstring(DEFAULT_SCRIPT);
exit(0);
} else {
i = argc;
while(i > 2) {
clone(argv[i-1]);
i --;
}
Scriptstring(argv[i-1]);
}
reapAll();
exit(0);
}
/* clone -- fork a copy to run a script */
void
clone(char *script)
{
int child_pid;
/* Log the event */
genLog("cloning ... ");
/* fork a new process */
child_pid = fork();
if (child_pid < 0) {
/* error, could not fork */
fprintf(stderr, "clone: fork failed--%s\n",
sys_errlist[errno]);
return;
} else if(child_pid == 0) {
/* execute the script */
Scriptstring(script);
reapAll();
exit(0);
}
fprintf(stderr, "child process %d cloned by %d.\n",
child_pid, getpid() );
}
/* reap a child process in response to SIGCLD */
void
reapSig( int sig)
{
int status;
(void) wait(&status);
sigset(SIGCLD, reapSig);
}
/* reap all child processes prior to exit */
void
reapAll()
{
int status;
/* wait for all children to exit */
for(;;) {
while(wait(&status) != -1) { };
if(errno == ECHILD) {
return;
}
}
}
/* a default scenario: does a number of different phases sequentially */
void
Scriptstring(char *script)
{
char *cmd;
char *j;
char prevj;
struct scripttab *k;
char buf[1024];
/* Log the event */
genLog("Begin script");
sprintf(buf, "\tbegin script `%s'\n", script);
fprintf(stderr, buf);
cmd = script;
while( (*cmd) != 0 ){
/* find the end of the next phase (a . or NULL) */
j = cmd;
while( ((*j) != 0) && ((*j) != '.') ) {
j++;
}
prevj = *j;
*j = 0;
/* now look up the phase in the table */
for (k = &scripttab[0]; ; k++) {
if(k->name == NULL) {
break;
}
if(strcmp(cmd, k->name) == 0) {
/* found a match */
(k->function)();
break;
}
}
if(k->name == NULL) {
sprintf(buf, "++ ignoring `%s'\n", cmd);
fprintf(stderr, buf);
}
/* continue processing */
*j = prevj;
cmd = j;
if(prevj != 0) {
cmd ++;
}
}
sprintf(buf, "\tend of script `%s'\n", script);
fprintf(stderr, buf);
genLog("End script");
}
/* Simple routines to execute various types of behaviors */
/*=======================================================*/
/* adddso -- add a DSO using sgidladd function */
#ifndef NONSHARED
static void *dl_object = NULL;
int
adddso()
{
int i;
/* see if already linked */
if(dl_object != NULL) {
fprintf(stderr, "libdso: dl_object already linked\n");
return 0;
}
/* Log the event */
genLog("start of adddso");
/* open the dynamic shared object */
dl_object = sgidladd(DYNSONAME, RTLD_LAZY);
if(dl_object == NULL) {
fprintf(stderr,
"adddso: sgidladd of %s failed--%s\n",
DYNSONAME, dlerror());
return 0;
}
/* invoke the routine */
i = dlslave_routine();
fprintf(stderr, "\tadddso: dynamic routine returned %d\n", i);
return 0;
}
#endif
/*=======================================================*/
/* beerbottles -- iterative exec */
int
beerbottles()
{
char count[1024];
int n = NBEERBOTTLES;
/* Log the event */
genLog("start of beerbottles");
sprintf(count, "%d", n);
execl("beerbottles", "beerbottles", count, NULL);
fprintf(stderr, "exectest: execl of `beerbottles' failed--%s\n",
sys_errlist[errno]);
exit(1);
return 0;
}
/*=======================================================*/
/* callsystem -- use system() to echo a string */
int
callsystem()
{
/* Log the event */
genLog("start of callsystem");
/* do the call */
system("echo \"system(echo) called from callsystem.\"");
fprintf(stderr, "\tcallsystem completed.\n");
return 0;
}
/*=======================================================*/
/* cvttrap - generate a bunch of FP traps (on some machines) */
#define IMAX 500000
int
cvttrap()
{
float y,z;
long i,n;
/* Log the event */
genLog("start of cvttrap");
y = 0.;
n = (long) 0x1f1f1f1f1f1f1f;
for(i = 0; i < IMAX; i ++ ) {
y = y + (float)n;
}
z = 0.;
n = (long) 0x1f1f1f1f1f;
for(i = 0; i < IMAX; i ++ ) {
z = z + (float)n;
}
fprintf(stderr, "\tcvttrap completed, y = %g, z = %g.\n",
y, z );
return 0;
}
/*=======================================================*/
/* dirstat - open a directory, stat its files */
int
dirstat()
{
char *dirname = DIRNAME;
DIR *dirp;
struct dirent *direntp;
int j = 0; /* count of entries read */
struct stat statb;
struct stat *statp = &statb;
char buf[1024];
/* Log the event */
genLog("start of dirstat");
/* open the directory */
dirp = opendir(dirname);
if(dirp == NULL) {
/* can't open the directory, just return */
return 0;
}
for (;;) {
direntp = readdir(dirp);
if(direntp == NULL) {
/* end of the directory */
sprintf(buf,
"\tdirstat of %s completed, %d files.\n",
dirname, j);
fprintf(stderr, buf);
closedir(dirp);
return 0;
}
j++;
/* got another entry, stat it */
(void) stat(direntp->d_name, statp);
}
}
/*=======================================================*/
/* exectest -- exec "nullprog" */
int
exectest()
{
/* Log the event */
genLog("start of exectest");
execl("nullprog", "nullprog", NULL);
fprintf(stderr, "exectest: execl of `nullprog' failed--%s\n",
sys_errlist[errno]);
exit(1);
return 0;
}
/*=======================================================*/
/* fpetraps - generate a bunch of fpe traps */
int
fpetraps()
{
int k;
float x, y, z;
/* Log the event */
genLog("start of fpetraps");
/* do some underflows */
x = 0.3;
for (k = 0; k < 10; k ++) {
x = x * x;
}
/* do some overflows */
x = 3.;
for (k = 0; k < 10; k ++) {
x = x * x;
}
/* divide by zero */
y = 0.;
x = 10.;
z = x/y;
x = z;
/* generate indefinite: 0/0 */
x = 0;
z = x/y;
x = z;
fprintf(stderr, "\tfpetraps completed.\n");
return 0;
}
/*=======================================================*/
/* forceabort - force a SEGV */
int
forceabort()
{
char *fname = NULL;
FILE *fp; /* FILE pointer for stdio */
int k; /* temp value for loop */
char c;
u_int size = 0;
/* Log the event */
genLog("start of forceabort");
/* and dereference a NULL */
c = *fname;
return 0;
}
/*=======================================================*/
/* iofile - do some file io operations */
int
iofile()
{
char *fname = IONAME;
FILE *fp; /* FILE pointer for stdio */
int k; /* temp value for loop */
char *buf;
u_int size = 0;
/* Log the event */
genLog("start of iofile -- stdio");
/* allocate a buffer for the reading */
/* note that this buffer is leaked! */
buf = (char *) malloc(BUFSIZE);
/* open the file */
fp = fopen(fname, "r");
/* loop, reading into the buffer */
for(;;) {
k = fread(buf, sizeof(char), BUFSIZE, fp);
if (k < 0) {
fprintf(stderr, "++ERROR reading %s, %s (%d)\n",
fname, sys_errlist[errno], errno );
} else {
size = size + k;
}
if (k != BUFSIZE) {
/* close the file */
fclose(fp);
/* short eread = EOF */
sprintf(buf,
"\tstdio iofile on %s completed, %d chars.\n",
fname, size);
fprintf(stderr, buf);
break;
}
}
return 0;
}
/*=======================================================*/
/* iotest - do various io syscalls */
int
iotest()
{
char *fname = "/usr/tmp/foobar";
int fd; /* file descriptor for raw IO */
int fd2; /* file descriptor for raw IO */
int k; /* temp value for loop */
char *buf;
u_int size = 0;
/* Log the regular read */
genLog("start of iotest");
/* create an empty file */
fd = creat(fname, 0666);
/* dup the file descriptor */
fd2 = dup(fd);
close(fd2);
close(fd);
/* now open the empty file */
fd = open(fname, O_RDONLY);
/* loop, reading into the buffer */
size = 0;
for(;;) {
k = read(fd, buf, BUFSIZE);
if (k < 0) {
fprintf(stderr, "++ERROR reading %s, %s (%d)\n",
fname, sys_errlist[errno], errno );
} else {
size = size + k;
}
if (k != BUFSIZE) {
/* close the file */
close(fd);
/* short eread = EOF */
break;
}
}
/* remove the file */
unlink(fname);
fprintf(stderr, "\tiotest completed.\n");
return 0;
}
/*=======================================================*/
/* linklist -- build a linked list of structures */
struct ll {
struct ll *next;
int index;
struct scripttab *tabentry;
char *name;
int (*function)(void);
};
struct ll *ll_first = NULL;
struct ll *ll_last = NULL;
int
linklist()
{
int i;
struct scripttab *k;
struct ll *ll_new;
/* Log the event */
genLog("start of linklist");
/* search the task table */
i = 0;
for (k = &scripttab[0]; ; k++) {
if(k->name == NULL) {
break;
}
/* allocate a structure */
ll_new = malloc(sizeof(struct ll) );
/* fill it in */
ll_new->next = NULL;
ll_new->index = i;
ll_new->tabentry = k;
ll_new->name =strdup(k->name);
ll_new->function = k->function;
/* link it into the list */
if (ll_first == NULL) {
ll_first = ll_new;
} else {
ll_last->next = ll_new;
}
ll_last = ll_new;
/* bump the index */
i ++;
}
fprintf(stderr, "\tlinklist completed.\n");
return 0;
}
/*=======================================================*/
/* libdso -- dynamically link a DSO, and call a routine in it */
#ifndef NONSHARED
int
libdso()
{
int i;
int (*dl_routine)();
char buf[1024];
/* see if already linked */
if(dl_object != NULL) {
fprintf(stderr, "libdso: dl_object already linked\n");
return 0;
}
/* Log the event */
genLog("start of libdso");
/* open the dynamic shared object */
dl_object = dlopen(DYNSONAME, RTLD_NOW);
if(dl_object == NULL) {
fprintf(stderr, "libdso: dlopen of %s failed--%s\n",
DYNSONAME, dlerror());
return 0;
}
/* look up the routine name in it */
dl_routine = (int (*)())dlsym(dl_object, DYNSOROUTINE);
if(dl_routine == NULL) {
fprintf(stderr, "libdso: dlsym %s not found\n",
DYNSOROUTINE);
return 0;
}
/* invoke the routine */
i = (*dl_routine)();
sprintf(buf, "\tlibdso: dynamic routine returned %d\n", i);
fprintf(stderr, buf);
return 0;
}
/*=======================================================*/
/* libdsoclose -- close a DSO */
int
libdsoclose()
{
int rc;
/* ensure already linked */
if(dl_object == NULL) {
fprintf(stderr, "libdsoclose: dl_object not linked\n");
return 0;
}
/* Log the event */
genLog("start of libdsoclose");
/* close the dynamic shared object */
rc = dlclose(dl_object);
if(rc != 0) {
fprintf(stderr, "libdso: dlclose failed--%s\n",
dlerror());
return 0;
}
/* clear the pointer */
dl_object = NULL;
fprintf(stderr, "\tlibdsoclose completed.\n");
return 0;
}
#endif
/*=======================================================*/
/* mallocerrors - allocate various blocks; make errors */
#ifndef NONSHARED
#define SIMPLE_SIZE 2047
/* find the CLEAR_FREE and CLEAR_MALLOC pattern size */
#if _MIPS_SZPTR == 32
typedef u_int32_t CLEAR_WORD;
#define MPRINT(ARG) fprintf(stderr, "0x%08x", ARG)
#else
typedef unsigned long long CLEAR_WORD;
#define MPRINT(ARG) fprintf(stderr, "0x%016llx", ARG)
#endif
static void
memcheck(void * ptr, int length)
{
CLEAR_WORD *mclear_ptr, mclear, leftover;
int i;
if (leftover = ((CLEAR_WORD) ptr % sizeof(CLEAR_WORD))) {
ptr = (void *) ((char *) ptr + sizeof(CLEAR_WORD) - leftover);
length -= sizeof(CLEAR_WORD) - leftover;
}
if (length < sizeof(CLEAR_WORD)) {
fprintf(stderr, "Memory check bypassed (length is too small).");
}
mclear_ptr = (CLEAR_WORD *) ptr;
mclear = mclear_ptr[0];
for (i = 1; i < length / sizeof (CLEAR_WORD); i++)
if (mclear != mclear_ptr[i]) {
mclear = mclear_ptr[i];
break;
}
if (mclear != mclear_ptr[0]) {
fprintf(stderr, "different values in memory block.");
} else {
fprintf(stderr, "same value (");
MPRINT(mclear);
fprintf(stderr, ") in memory block.");
}
}
int
mallocerrors()
{
long long stackvar;
int ralph;
char *simple;
char *csimple;
char *clear;
char *clear2;
char *page;
int alignment;
long long *mal;
/* Log the event */
genLog("start of mallocerrors");
/* a simple malloc and free */
fprintf(stderr, " Simple malloc(%d)\n", SIMPLE_SIZE);
if (simple = (char *)malloc(SIMPLE_SIZE)) {
fprintf(stderr, " succeeded, block address ");
MPRINT(simple);
fprintf(stderr, "\n");
/* check MALLOC_CLEAR_MALLOC */
fprintf(stderr, " ");
memcheck((void *) simple, SIMPLE_SIZE);
fprintf(stderr, "\n");
/* free simple */
fprintf(stderr, " freeing block @");
MPRINT(simple);
fprintf(stderr, "...\n");
free(simple);
/* check MALLOC_CLEAR_FREE */
fprintf(stderr, " ");
memcheck((void *) simple, SIMPLE_SIZE);
fprintf(stderr, "\n");
} else {
fprintf(stderr, " failed\n");
}
/* a malloc for a string without zero-byte, and overrun it */
fprintf(stderr, " Trying malloc(strlen(\"bad\"))...\n");
if (csimple = (char *)malloc(strlen("bad") )) {
fprintf(stderr, " succeeded, block address ");
MPRINT(csimple);
fprintf(stderr, "\n");
fprintf(stderr, " then copy \"bad\" to it using strcpy()\n");
strcpy(csimple, "bad");
fprintf(stderr, " then free it...\n");
free(csimple);
} else {
fprintf(stderr, " failed\n");
}
/* a simple malloc, followed by overrun */
fprintf(stderr, " Trying malloc(%d)...\n", SIMPLE_SIZE);
if (simple = (char *)malloc(SIMPLE_SIZE)) {
fprintf(stderr, " succeeded, block address ");
MPRINT(simple);
fprintf(stderr, "\n");
fprintf(stderr, " then write to array[size + 1]...\n");
simple[SIMPLE_SIZE + 1] = 0;
fprintf(stderr, " and free it...\n");
free(simple);
} else {
fprintf(stderr, " failed\n");
}
/* a calloc, followed by a realloc */
fprintf(stderr, " Trying calloc(1010, 2)...\n");
if (clear = (char *)calloc(1010, 2)) {
fprintf(stderr, " succeeded, block address ");
MPRINT(clear);
fprintf(stderr, "\n");
fprintf(stderr, " ");
memcheck((void *) clear, 2020);
fprintf(stderr, "\n");
fprintf(stderr, " then realloc() to 3000...\n");
if (clear2 = (char *)realloc((void*)clear, 3000)) {
fprintf(stderr, " succeeded, block address ");
MPRINT(clear2);
fprintf(stderr, "\n");
fprintf(stderr, " ");
memcheck((void *) clear2, 3000);
fprintf(stderr, "\n");
fprintf(stderr, " then free it...\n");
free(clear2);
fprintf(stderr, " ");
memcheck((void *) clear2, 3000);
fprintf(stderr, "\n");
} else {
fprintf(stderr, " failed\n");
fprintf(stderr, " Maybe free the old pointer?\n");
free(clear);
}
} else {
fprintf(stderr, " failed\n");
}
/* malloc 1 byte, then realloc to 3 */
fprintf(stderr, " Allocate one byte...\n");
if (simple = (char *)malloc(1)) {
fprintf(stderr, " succeeded, block address ");
MPRINT(simple);
fprintf(stderr, "\n");
fprintf(stderr, " realloc() to 3 bytes...\n");
if (csimple = (char *)realloc(simple, 3)) {
fprintf(stderr, " succeeded, block address ");
MPRINT(csimple);
fprintf(stderr, "\n");
fprintf(stderr, " then free it...\n");
free(csimple);
} else {
fprintf(stderr, " failed\n");
fprintf(stderr, " Maybe free the old pointer?\n");
free(simple);
}
} else {
fprintf(stderr, " failed\n");
}
/* malloc 31 bytes, then realloc to 1 */
fprintf(stderr, " Allocate 31 bytes...\n");
if (simple = (char *)malloc(31)) {
fprintf(stderr, " succeeded, block address ");
MPRINT(simple);
fprintf(stderr, "\n");
fprintf(stderr, " realloc() to 1 bytes...\n");
if (csimple = (char *)realloc(simple, 1)) {
fprintf(stderr, " succeeded, block address ");
MPRINT(csimple);
fprintf(stderr, "\n");
fprintf(stderr, " then free it...\n");
free(csimple);
} else {
fprintf(stderr, " failed\n");
fprintf(stderr, " Maybe free the old pointer?\n");
free(simple);
}
} else {
fprintf(stderr, " failed\n");
}
/* a valloc */
fprintf(stderr, " Try valloc(%d)...\n", SIMPLE_SIZE);
if (page = (char *)valloc(SIMPLE_SIZE)) {
fprintf(stderr, " succeeded, block address ");
MPRINT(page);
fprintf(stderr, "\n");
fprintf(stderr, " free it...\n");
free(page);
} else {
fprintf(stderr, " failed\n");
}
/* a memalign to 16 bytes */
fprintf(stderr, " A memalign() at 16-byte boundary...\n");
alignment = 16;
if (mal = (long long *)memalign(alignment, 40*sizeof(long long))) {
fprintf(stderr, " succeeded, block address ");
MPRINT(mal);
fprintf(stderr, "\n");
fprintf(stderr, " free it...\n");
free(mal);
} else {
fprintf(stderr, " failed\n");
}
/* a memalign to 16 bytes, check overrun */
fprintf(stderr, " Another memalign() at 16-byte boundary, 3 bytes\n");
alignment = 16;
if (mal = (long long *)memalign(alignment, 3)) {
fprintf(stderr, " succeeded, block address ");
MPRINT(mal);
fprintf(stderr, "\n");
fprintf(stderr, " put zero in [pointer + 3]...\n");
clear = (char *) mal + 3;
*clear = '\0';
fprintf(stderr, " free it...\n");
free(mal);
} else {
fprintf(stderr, " failed\n");
}
/* a memalign to 16 bytes, check overrun */
fprintf(stderr, " Another memalign() at 16-byte boundary, 3 bytes\n");
alignment = 16;
if (mal = (long long *)memalign(alignment, 3)) {
fprintf(stderr, " succeeded, block address ");
MPRINT(mal);
fprintf(stderr, "\n");
fprintf(stderr, " put zero in [pointer + 3]...\n");
clear = (char *) mal + 3;
*clear = '\0';
fprintf(stderr, " then realloc() it to 11 bytes...\n");
if (simple = realloc(mal, 11)) {
fprintf(stderr, " succeeded, block address ");
MPRINT(simple);
fprintf(stderr, "\n");
fprintf(stderr, " finally free it...\n");
free(simple);
} else {
fprintf(stderr, " failed\n");
fprintf(stderr, " Maybe free the old pointer?\n");
free(mal);
}
} else {
fprintf(stderr, " failed\n");
}
/* a memalign to 64 bytes */
fprintf(stderr, " A memalign() at 64-byte boundary...\n");
alignment = 64;
if (mal = (long long *)memalign(alignment, 40*sizeof(long long))) {
fprintf(stderr, " succeeded, block address ");
MPRINT(mal);
fprintf(stderr, "\n");
fprintf(stderr, " free it...\n");
free(mal);
fprintf(stderr, " How about free it twice?\n");
free(mal);
} else {
fprintf(stderr, " failed\n");
}
/* Bad alignment */
fprintf(stderr, " Trying to get aligned at 48-byte boundary...\n");
if (simple = (char*)memalign(48, 1024)) {
fprintf(stderr, " succeeded, block address ");
MPRINT(simple);
fprintf(stderr, "\n");
} else {
/* should be here */
fprintf(stderr, " failed\n");
}
fprintf(stderr, " But free it anyways...\n");
free(simple);
/* a memalign to 16 bytes */
fprintf(stderr, " A memalign(16, ~8K)...\n");
alignment = 16;
if (mal = (long long *)memalign(alignment, 4 * SIMPLE_SIZE)) {
fprintf(stderr, " succeeded, block address ");
MPRINT(mal);
fprintf(stderr, "\n");
fprintf(stderr, " free it...\n");
free(mal);
} else {
fprintf(stderr, " failed\n");
}
/* bad size */
fprintf(stderr, " Trying to allocate 0 byte...\n");
if (simple = (char*)malloc(0)) {
fprintf(stderr, " succeeded, block address ");
MPRINT(simple);
fprintf(stderr, "\n");
fprintf(stderr, " free it...\n");
free(simple);
} else {
fprintf(stderr, " failed\n");
}
/* size too big */
fprintf(stderr, " Trying to allocate a big chunk (~8K)...\n");
if (simple = (char*)malloc(4 * SIMPLE_SIZE)) {
fprintf(stderr, " succeeded, block address ");
MPRINT(simple);
fprintf(stderr, "\n");
fprintf(stderr, " do not free it...\n");
} else {
fprintf(stderr, " failed\n");
}
/* misaligned realloc address */
fprintf(stderr, " Trying to realloc() an odd address pointer...\n");
if (simple = (char*)realloc((void*) ((char *)&ralph + 1), 64)) {
fprintf(stderr, " succeeded, block address ");
MPRINT(simple);
fprintf(stderr, "\n");
fprintf(stderr, " free it...\n");
free(simple);
} else {
fprintf(stderr, " failed\n");
}
/* realloc size too big */
fprintf(stderr, " Trying to realloc() a big chunk (~8K)...\n");
if (simple = (char*)realloc(malloc(1), 4 * SIMPLE_SIZE)) {
fprintf(stderr, " succeeded, block address ");
MPRINT(simple);
fprintf(stderr, "\n");
fprintf(stderr, " free it...\n");
free(simple);
} else {
fprintf(stderr, " failed\n");
}
/* a simple malloc, followed by overrun */
fprintf(stderr, " Trying malloc(%d)...\n", 11);
if (simple = (char *)malloc(11)) {
fprintf(stderr, " succeeded, block address ");
MPRINT(simple);
fprintf(stderr, "\n");
fprintf(stderr, " then write to array[size + 1]...\n");
simple[11 + 1] = 0;
fprintf(stderr, " and realloc() to 1...\n");
if (realloc(simple, 1)) {
fprintf(stderr, " succeeded!\n");
} else {
fprintf(stderr, " failed!\n");
}
/* leaking */
} else {
fprintf(stderr, " failed\n");
}
/* bad realloc address */
fprintf(stderr, " Trying to realloc(&an_auto_variable, 64)...\n");
if (simple = (char*)realloc((void*) &ralph, 64)) {
fprintf(stderr, " succeeded, block address ");
MPRINT(simple);
fprintf(stderr, "\n");
fprintf(stderr, " free it...\n");
free(simple);
} else {
fprintf(stderr, " failed\n");
}
/* free of a misaligned address */
fprintf(stderr, " Freeing an odd address pointer...\n");
free( (char *)(&stackvar) + 1 );
/* free of a stack address */
fprintf(stderr, " Trying free(&an_auto_variable)...\n");
free(&stackvar);
/* allocate something but don't free */
fprintf(stderr, " Get one byte...\n");
if (simple = (char*)malloc(1)) {
fprintf(stderr, " succeeded, block address ");
MPRINT(simple);
fprintf(stderr, "\n");
fprintf(stderr, " But I'm not going to free it...\n");
} else {
fprintf(stderr, " failed\n");
}
/* print out message saying we are back */
fprintf(stderr, "...\tmallocerrors completed (pid = %d)\n", getpid());
return 0;
}
int
mallocerrors_extra()
{
int ralph;
char *simple;
/* Log the event */
genLog("start of mallocerrors-extra");
/* a simple malloc, followed by underrun */
fprintf(stderr, " Trying malloc(%d) again...\n", SIMPLE_SIZE);
ralph = -4;
if (simple = (char *)malloc(SIMPLE_SIZE)) {
fprintf(stderr, " succeeded, block address ");
MPRINT(simple);
fprintf(stderr, "\n");
fprintf(stderr, " then write to array[-4]...\n");
simple[ralph] = 1;
fprintf(stderr, " and free it...\n");
free(simple);
} else {
fprintf(stderr, " failed\n");
}
/* corrupt data */
fprintf(stderr, " Get memalign(16, 1)...\n");
if (simple = (char*)memalign(16, 1)) {
fprintf(stderr, " succeeded, block address ");
MPRINT(simple);
fprintf(stderr, "\n");
fprintf(stderr,
" Put 0xff in a byte 3 words ahead of it...\n");
*(simple - 3 * sizeof(CLEAR_WORD)) = 0xff;
fprintf(stderr, " then free it...\n");
free(simple);
} else {
fprintf(stderr, " failed\n");
}
/* corrupt data */
fprintf(stderr, " Get memalign(16, 1) again...\n");
if (simple = (char*)memalign(16, 1)) {
fprintf(stderr, " succeeded, block address ");
MPRINT(simple);
fprintf(stderr, "\n");
fprintf(stderr,
" Put 0xff in a byte 3 words ahead of it...\n");
*(simple - 3 * sizeof(CLEAR_WORD)) = 0xff;
fprintf(stderr, " then realloc it...\n");
simple = realloc(simple, 1);
} else {
fprintf(stderr, " failed\n");
}
/* a simple malloc, followed by underrun */
fprintf(stderr, " Trying malloc(%d) again...\n", 11);
ralph = -4;
if (simple = (char *)malloc(11)) {
fprintf(stderr, " succeeded, block address ");
MPRINT(simple);
fprintf(stderr, "\n");
fprintf(stderr, " then write to array[-4]...\n");
simple[ralph] = 1;
fprintf(stderr, " and free it...\n");
if (realloc(simple, 1)) {
fprintf(stderr, " succeeded!\n");
} else {
fprintf(stderr, " failed!\n");
}
/* leaking */
} else {
fprintf(stderr, " failed\n");
}
/* mallocate something */
fprintf(stderr, " Malloc one byte...\n");
if (simple = (char*)malloc(1)) {
fprintf(stderr, " succeeded, block address ");
MPRINT(simple);
fprintf(stderr, "\n");
fprintf(stderr, " freeing it the first time\n");
free(simple);
fprintf(stderr, " freeing it the second time\n");
free(simple);
} else {
fprintf(stderr, " failed\n");
}
/* print out message saying we are back */
fprintf(stderr, "...\tmallocerrors-extra completed (pid = %d)\n", getpid());
return 0;
}
/*=======================================================*/
/* mp_mallocs - multi-process calling "mallocerrors()" */
#define MP_MALLOCS 5
static void
mp_wrapper(void *ptr)
{
barrier((barrier_t *) ptr, MP_MALLOCS);
mallocerrors();
mallocerrors_extra();
}
int
mp_mallocs()
{
char *name;
usptr_t *arena;
barrier_t *bar;
int i;
/* Log the event */
genLog("multi-process malloc tests");
/* initialize the barrier */
usconfig(CONF_ARENATYPE, US_SHAREDONLY);
if (!(name = tempnam("/usr/tmp/", "mpme"))) {
perror("TEMPNAM");
return 0;
}
if (!(arena = usinit(name))) {
perror("USINIT");
return 0;
}
if (!(bar = new_barrier(arena))) {
perror("NEW_BARRIER");
return 0;
}
init_barrier(bar);
/* create the processes */
for (i = 0; i < MP_MALLOCS; i ++) {
if (sproc(mp_wrapper, PR_SALL, (void*) bar) == -1) {
perror("SPROC");
}
}
fprintf(stderr, "...\tMP-me returning (pid = %d)\n", getpid());
return 0;
}
#endif /* NONSHARED */
/*=======================================================*/
/* memthrash - allocate some memory, and thrash around in it */
int
memthrash()
{
unsigned long size;
unsigned long addr;
void *region;
long npages;
long i;
/* Log the event */
genLog("start of memthrash");
/* compute the size */
size = THRASHMB*1024*1024;
pagesize = getpagesize();
region = malloc(size + pagesize);
if(region == NULL) {
fprintf(stderr,
"\tmemthrash failed; can't get %ld bytes.\n",
size);
return 0;
}
/* round address to page boundary */
addr =(((unsigned long)region + pagesize -1) & (~(pagesize-1)));
npages = size /pagesize;
/* touch all the pages to force them in */
for (i = 0; i < npages; i ++) {
*(int *)(addr + i*pagesize) = i;
}
/* now free up the region */
free(region);
fprintf(stderr, "\tmemthrash completed, %ld pages.\n", npages);
return 0;
}
/*=======================================================*/
/* sproctest - sproc another thread, and do something in it */
int
sproctest()
{
int index;
int n = NSPROCS;
/* Log the event */
genLog("start of sproctest");
fprintf(stderr, "sproc -- number of children %d\n", n);
/* make sure the arena is big enough */
usconfig(CONF_INITUSERS, (2*NSPROCS + 5) );
for (index = 0; index < n; index++) {
int child = sproc (sproctestchild, PR_SADDR);
if (child == -1) {
perror("SPROC CHILD");
}
}
fprintf(stderr, "\tsproctest completed.\n");
return 0;
}
void
sproctestchild(void *arg)
{
int grand_child = sproc (sproctestgrandchild, PR_SADDR);
if (grand_child == -1) {
perror("SPROC GRANDCHILD");
}
sproctestgrandchild(arg);
}
void
sproctestgrandchild(void *arg)
{
int index;
long *sequence;
long long argx;
argx = (long long) arg;
sequence = (long *) malloc(
NSPROCMALLOCS * sizeof (long) );
for (index = 0; index < NSPROCMALLOCS; index++) {
sequence[index] = index;
}
free (sequence);
fprintf(stderr,
"sproc descendant, pid: %d, arg =0x%08llx completed.\n",
getpid(), argx);
}
/*=======================================================*/
/* usrtime - loop to use a bunch of user time */
int
usrtime()
{
int j; /* temp value for loop */
int k; /* temp value for loop */
float x; /* temp variable for f.p. calculation */
/* Log the event */
genLog("start of usrtime");
#if 0
for (k = 0; k < 100; k ++) {
x = 0.0;
for(j=0; j<100000; j++) {
x = x + 1.0;
}
}
#endif
anneal();
fprintf(stderr, "\tusertime completed.\n");
return 0;
}
/*
* Here's the array annealing routine, snipped out. I've provided
* a local variable, "delay," that makes the annealing take longer;
* (very) roughly speaking, it takes about 10*delay iterations to
* converge. The present default of 100 seems to give
* just-noticable change from step to step.
*/
#include <limits.h>
#include <stdlib.h>
#include <math.h>
typedef double tArrayElem; /* "long long" and "double" are fun, too */
#define TWODARRAYSIZE 40
#define MAX_ANNEAL 10000
const int twoDarraySize = TWODARRAYSIZE; /* bigger is better */
typedef enum {randomly, sinusoidal, zero} tclampStyle;
tclampStyle clampStyle = zero; /* sinusoidal is the coolest, but zero */
/* is the easiest to understand */
tArrayElem twoDarray[TWODARRAYSIZE][TWODARRAYSIZE];
void init2da();
void
init2da()
{
/* Randomize interior, clamp edges to an interesting pattern */
const double circ = 4*twoDarraySize - 4;
const double pi = 3.1415926535;
const double incr = 2*pi/circ;
double phase = 0.0;
int i, j;
/* Randomize the whole array, then clamp as specified in command */
for (i = 0; i < (twoDarraySize); i++) {
for (j = 0; j < (twoDarraySize); j++) {
twoDarray[i][j] = 5. * drand48();
}
}
switch (clampStyle) {
case sinusoidal:
for (i = 0, j = 0; i < twoDarraySize; i++) {
twoDarray[i][j] = sinf(phase);
phase += incr;
}
i--; /* Undo loop-end incr */
for (j = 1; j < twoDarraySize; j++) {
twoDarray[i][j] = sinf(phase);
phase += incr;
}
j--;
for (i = i-1; i >= 0; i--) {
twoDarray[i][j] = sinf(phase);
phase += incr;
}
i++;
for (j = j-1; j >= 0; j--) {
twoDarray[i][j] = sinf(phase);
phase += incr;
}
j++;
for (i = 0, j = 0; i < twoDarraySize; i++) {
twoDarray[i][j] = sinf(phase);
phase += incr;
}
i--; /* Undo loop-end incr */
for (j = 1; j < twoDarraySize; j++) {
twoDarray[i][j] = sinf(phase);
phase += incr;
}
j--;
for (i = i-1; i >= 0; i--) {
twoDarray[i][j] = sinf(phase);
phase += incr;
}
i++;
for (j = j-1; j >= 0; j--) {
twoDarray[i][j] = sinf(phase);
phase += incr;
}
j++;
for (i = 0, j = 0; i < twoDarraySize; i++) {
twoDarray[i][j] = sinf(phase);
phase += incr;
}
i--; /* Undo loop-end incr */
for (j = 1; j < twoDarraySize; j++) {
twoDarray[i][j] = sinf(phase);
phase += incr;
}
j--;
for (i = i-1; i >= 0; i--) {
twoDarray[i][j] = sinf(phase);
phase += incr;
}
i++;
for (j = j-1; j >= 0; j--) {
twoDarray[i][j] = sinf(phase);
phase += incr;
}
j++;
for (i = 0, j = 0; i < twoDarraySize; i++) {
twoDarray[i][j] = sinf(phase);
phase += incr;
}
i--; /* Undo loop-end incr */
for (j = 1; j < twoDarraySize; j++) {
twoDarray[i][j] = sinf(phase);
phase += incr;
}
j--;
for (i = i-1; i >= 0; i--) {
twoDarray[i][j] = sinf(phase);
phase += incr;
}
i++;
for (j = j-1; j >= 0; j--) {
twoDarray[i][j] = sinf(phase);
phase += incr;
}
j++;
break;
case zero:
for (i = 0; i < twoDarraySize; i++) {
twoDarray[0][i] =
twoDarray[i][0] =
twoDarray[twoDarraySize-1][i] =
twoDarray[i][twoDarraySize-1] =
0;
}
break;
case randomly:
default:
break;
}
}
void
anneal()
{
int i,j,k;
double delay = 100.0;
clampStyle = sinusoidal;
init2da();
/* Anneal only the interior (edges are clamped by init2da()) */
/* To fix the failure to anneal in -sine mode, uncomment the cast
* to float.
*/
for (k = 0; k < MAX_ANNEAL; k ++) {
/* breakpoint here to watch the array */
for (i = 1; i < (twoDarraySize-1); i++) {
for (j = 1; j < (twoDarraySize-1); j++) {
twoDarray[i][j] =
( twoDarray[i-1][j-1]
+ twoDarray[i-1][j]
+ twoDarray[i-1][j+1]
+ twoDarray[i][j-1]
+ twoDarray[i][j] * delay
+ twoDarray[i][j+1]
+ twoDarray[i+1][j-1]
+ twoDarray[i+1][j]
+ twoDarray[i+1][j+1] )
/ (delay+8);
}
}
}
}
/*=======================================================*/
/* genCvtime (ttime)
* returns a pointer to a static string in the form:
* Thu 01 Jan 1990 00:00:00\0
* 01234567890122345678901234
*
* ttime is a pointer to a UNIX time in seconds since epoch
* library routine localtime() is used
*
*/
static char genccbuf[26];
static char *days[] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
static char *months[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
char *
genCvtime (time_t *ttime)
{
struct tm *tp;
/* get the date and time */
tp = localtime(ttime);
/* convert to string */
sprintf(genccbuf, "%s %02d %s %04d %02d:%02d:%02d",
days[tp->tm_wday],
tp->tm_mday,
months[tp->tm_mon],
1900 + tp->tm_year,
tp->tm_hour,
tp->tm_min,
tp->tm_sec);
return(genccbuf);
}
static char genccbuf2[26];
char *
genCvDeltaTime(struct timeval tempus)
{
long seconds;
long minutes;
long hours;
while (tempus.tv_usec < 0 ) {
tempus.tv_sec --;
tempus.tv_usec += 1000000;
}
seconds = tempus.tv_sec % 60;
minutes = tempus.tv_sec/60;
hours = minutes/60;
minutes = minutes % 60;
sprintf(genccbuf2, "%01ld:%02ld:%02ld.%03ld ",
hours, minutes, seconds, tempus.tv_usec/1000);
return(genccbuf2);
}
void
genTraceSnapTime()
{
/* struct timezone tz; */
(void) gettimeofday(&ttime, NULL);
deltatime.tv_sec = ttime.tv_sec - starttime.tv_sec;
deltatime.tv_usec = ttime.tv_usec - starttime.tv_usec;
}
void
genLog(char *event)
{
time_t secs;
char buf[1024];
genTraceSnapTime();
secs = (time_t)ttime.tv_sec;
sprintf(buf,
"%s======== (%d) %24s %s.\n",
genCvDeltaTime(deltatime),
getpid(),
event,
genCvtime(&secs));
fprintf(stderr, buf);
}